package com.ueboot.weishop.admin.controller.setting;

import com.ueboot.core.exception.BusinessException;
import com.ueboot.core.http.response.Response;
import com.ueboot.weishop.admin.controller.setting.vo.AreaFindReq;
import com.ueboot.weishop.admin.controller.setting.vo.AreaReq;
import com.ueboot.weishop.admin.controller.setting.vo.AreaResp;
import com.ueboot.weishop.entity.setting.AreaEntity;
import com.ueboot.weishop.service.area.AreaService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Neel on 2017/9/18.
 */
@Slf4j
@RestController
@RequestMapping(value = "/areas")
public class AreaController {

    @Autowired
    private AreaService areaService;

    @RequiresPermissions("areas:read")
    @RequestMapping(value = "/page", method = RequestMethod.POST)
    public Response<Page<AreaResp>> page(@PageableDefault(value = 15, sort = {"id"}, direction = Sort.Direction.DESC) Pageable pageable, @RequestBody(required = false) AreaFindReq req) {
        Page<AreaEntity> entities = areaService.findBy(pageable);
        Page<AreaResp> body = entities.map(entity -> {
            AreaResp resp = new AreaResp();
            BeanUtils.copyProperties(entity, resp);

            resp.setParentIds(entity.getFullPathId() == null ? new Long[]{} : (Long[])ConvertUtils.convert(entity.getFullPathId().split("/"), Long[].class));
            resp.setParentId(entity.getParent() == null ? null : entity.getParent().getId());
            return resp;
        });
        return new Response<>(body);
    }


    @RequiresPermissions("areas:save")
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public Response<Void> save(@RequestBody AreaReq req) {
        AreaEntity entity = null;
        if (req.getId() == null) {
            entity = new AreaEntity();
        } else {
            entity = areaService.get(req.getId());
        }
        BeanUtils.copyProperties(req, entity);
        AreaEntity parent = null;
        if (req.getParentIds() != null && req.getParentIds().length > 0) {
            parent = areaService.get(req.getParentIds()[req.getParentIds().length - 1]);
            entity.setLevel(parent.getLevel() + 1);
            entity.setParent(parent);
            entity.setFullPathName(parent == null || parent.getFullPathName() == null ?  null : parent.getFullPathName() + parent.getName() + "/");
            entity.setFullPathId(parent == null || parent.getFullPathId() == null ? null : parent.getFullPathId() + parent.getId() + "/");
        } else {
            entity.setLevel(1);
            entity.setFullPathName(null);
            entity.setFullPathId(null);
        }

        areaService.save(entity);

        return new Response<>();
    }


    @RequiresPermissions("areas:delete")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public Response<Void> delete(Long[] id) {

        for (Long ID : id) {
            List<AreaEntity> list = areaService.findByParentId(ID);
            if (!list.isEmpty()) {
                throw new BusinessException("请先删除子地区，才能删除该地区");
            }
        }

        areaService.delete(id);
        return new Response<>();
    }


    @RequiresPermissions("areas:read")
    @RequestMapping(value = "/find", method = RequestMethod.POST)
    public Response<List<AreaResp>> find() {
        List<AreaEntity> result = areaService.findAll();
        List<AreaResp> list = new ArrayList<>();
        result.forEach(item -> {
            AreaResp resp = new AreaResp();
            BeanUtils.copyProperties(item, resp);

            resp.setParentId(item.getParent() == null ? null : item.getParent().getId());
            resp.setParentIds(item.getFullPathId() == null ? new Long[]{} : (Long[])ConvertUtils.convert(item.getFullPathId().split("/"), Long[].class));

            resp.setValue(item.getId());
            list.add(resp);
        });
        return new Response<>(list);
    }


    @RequiresPermissions("areas:read")
    @RequestMapping(value = "/dealers", method = RequestMethod.POST)
    public Response<List<AreaResp>> dealers(Long parentId) {
        AreaEntity entity = parentId == null ? null : areaService.get(parentId);

        List<AreaEntity> result = areaService.findByFullPathIdStartingWithAndLevel(entity == null ? null : entity.getFullPathId(), entity == null ? 1 : entity.getLevel() + 1);
        List<AreaResp> list = new ArrayList<>();
        result.forEach(item -> {
            AreaResp resp = new AreaResp();
            BeanUtils.copyProperties(item, resp);
            resp.setParentId(item.getParent() == null ? null : item.getParent().getId());
            resp.setValue(item.getId());
            list.add(resp);
        });
        return new Response<>(list);
    }

}
